package com.jt.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//能否利用一个工厂动态为目标对象创建代理
public class JDKProxyFactory {
    //关于匿名内部类用法说明：匿名内部类引用外部参数  要求参数必须final
    public static Object getProxy(final Object target){

        /*
        *参数分析：
        * 1.ClassLoader classloader  获取类加载器（获取目标对象的Class）（类似.class、getClass、forName）
        * 2.Class<?> [] interfaces获取类的接口数组，jdk代理要求必须有接口
        * 3.InvocationHandler h 对目标方法进行扩展
        * */
        //1.获取类加载器
        //在JVM中，一个类用其全限定类名和其类加载器作为其唯一标识
        ClassLoader classLoader = target.getClass().getClassLoader();
        //2.获取接口数组
        Class[] interfaces = target.getClass().getInterfaces();
        //Returns an instance of a proxy class for the specified interfaces
        Object proxy = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //目标方法执行的返回值
                Object result = null;
                try {
                    System.out.println("事务开始");
                    result = method.invoke(target,args);    //执行目标方法
                    System.out.println("事务提交");
                    return result;
                }catch (Exception e){
                    e.printStackTrace();
                    System.out.println("事务回滚");
                }
                return result;
            }
        });
        return proxy;
    }
}
